home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / sd-26.zip / sdtop.c < prev    next >
C/C++ Source or Header  |  1992-09-09  |  29KB  |  642 lines

  1. /* SD -- square dance caller's helper.
  2.  
  3.     Copyright (C) 1990, 1991, 1992  William B. Ackerman.
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 1, or (at your option)
  8.     any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19.     This is version 24.0. */
  20.  
  21. /* This defines the following functions:
  22.    update_id_bits
  23.    touch_or_rear_back
  24.    toplevelmove
  25. */
  26.  
  27. #include "sd.h"
  28.  
  29. typedef struct {
  30.    short source_indices[16];
  31.    int size;
  32.    setup_kind outer_kind;
  33.    int rot;
  34.    } expand_thing;
  35.  
  36. typedef struct {
  37.    int warning;
  38.    int forbidden_elongation;
  39.    expand_thing *expand_lists;
  40.    } full_expand_thing;
  41.  
  42. static expand_thing exp_1x8_4dm_stuff   = {{12, 13, 15, 14, 4, 5, 7, 6}, 8, s_4dmd, 0};
  43. static expand_thing exp_qtg_4dm_stuff   = {{1, 2, 6, 7, 9, 10, 14, 15}, 8, s_4dmd, 0};
  44. static expand_thing exp_3x1d_3d_stuff   = {{9, 10, 11, 1, 3, 4, 5, 7}, 8, s_3dmd, 0};
  45. static expand_thing exp_4x4_4dm_stuff_a = {{8, 9, 10, 6, 11, 13, 12, 15, 0, 1, 2, 14, 3, 5, 4, 7}, 16, s_4dmd, 1};
  46. static expand_thing exp_4x4_4dm_stuff_b = {{3, 4, 5, 6, 8, 9, 10, 7, 11, 12, 13, 14, 0, 1, 2, 15}, 16, s_4dmd, 0};
  47. static expand_thing exp_2x4_2x6_stuff   = {{1, 2, 3, 4, 7, 8, 9, 10}, 8, s2x6, 0};
  48. static expand_thing exp_qtg_3x4_stuff   = {{1, 2, 4, 5, 7, 8, 10, 11}, 8, s3x4, 0};
  49. static expand_thing exp_2x6_2x8_stuff   = {{1, 2, 3, 4, 5, 6, 9, 10, 11, 12, 13, 14}, 12, s2x8, 0};
  50. static expand_thing exp_2x6_4x6_stuff   = {{11, 10, 9, 8, 7, 6, 23, 22, 21, 20, 19, 18}, 12, s4x6, 0};
  51. static expand_thing exp_2x4_2x8_stuff   = {{2, 3, 4, 5, 10, 11, 12, 13}, 8, s2x8, 0};
  52. static expand_thing exp_2x4_4x4_stuff   = {{10, 15, 3, 1, 2, 7, 11, 9}, 8, s4x4, 0};
  53. static expand_thing exp_4x4_blob_stuff  = {{3, 4, 8, 5, 9, 10, 14, 11, 15, 16, 20, 17, 21, 22, 2, 23}, 16, s_bigblob, 0};
  54.  
  55. static int bit_table_2x2[][4] = {
  56.    {ID2_LEAD|ID2_BEAU,     ID2_TRAILER|ID2_BEAU,  ID2_TRAILER|ID2_BELLE, ID2_LEAD|ID2_BELLE},
  57.    {ID2_LEAD|ID2_BELLE,    ID2_LEAD|ID2_BEAU,     ID2_TRAILER|ID2_BEAU,  ID2_TRAILER|ID2_BELLE},
  58.    {ID2_TRAILER|ID2_BELLE, ID2_LEAD|ID2_BELLE,    ID2_LEAD|ID2_BEAU,     ID2_TRAILER|ID2_BEAU},
  59.    {ID2_TRAILER|ID2_BEAU,  ID2_TRAILER|ID2_BELLE, ID2_LEAD|ID2_BELLE,    ID2_LEAD|ID2_BEAU}};
  60.  
  61. static int bit_table_2x4[][4] = {
  62.    {ID2_LEAD|ID2_BEAU|ID2_END,        ID2_TRAILER|ID2_BEAU|ID2_END,     ID2_TRAILER|ID2_BELLE|ID2_END,    ID2_LEAD|ID2_BELLE|ID2_END},
  63.    {ID2_LEAD|ID2_BELLE|ID2_CENTER,    ID2_LEAD|ID2_BEAU|ID2_CENTER,     ID2_TRAILER|ID2_BEAU|ID2_CENTER,  ID2_TRAILER|ID2_BELLE|ID2_CENTER},
  64.    {ID2_LEAD|ID2_BEAU|ID2_CENTER,     ID2_TRAILER|ID2_BEAU|ID2_CENTER,  ID2_TRAILER|ID2_BELLE|ID2_CENTER, ID2_LEAD|ID2_BELLE|ID2_CENTER},
  65.    {ID2_LEAD|ID2_BELLE|ID2_END,       ID2_LEAD|ID2_BEAU|ID2_END,        ID2_TRAILER|ID2_BEAU|ID2_END,     ID2_TRAILER|ID2_BELLE|ID2_END},
  66.    {ID2_TRAILER|ID2_BELLE|ID2_END,    ID2_LEAD|ID2_BELLE|ID2_END,       ID2_LEAD|ID2_BEAU|ID2_END,        ID2_TRAILER|ID2_BEAU|ID2_END},
  67.    {ID2_TRAILER|ID2_BEAU|ID2_CENTER,  ID2_TRAILER|ID2_BELLE|ID2_CENTER, ID2_LEAD|ID2_BELLE|ID2_CENTER,    ID2_LEAD|ID2_BEAU|ID2_CENTER},
  68.    {ID2_TRAILER|ID2_BELLE|ID2_CENTER, ID2_LEAD|ID2_BELLE|ID2_CENTER,    ID2_LEAD|ID2_BEAU|ID2_CENTER,     ID2_TRAILER|ID2_BEAU|ID2_CENTER},
  69.    {ID2_TRAILER|ID2_BEAU|ID2_END,     ID2_TRAILER|ID2_BELLE|ID2_END,    ID2_LEAD|ID2_BELLE|ID2_END,       ID2_LEAD|ID2_BEAU|ID2_END}};
  70.  
  71. static int bit_table_1x2[][4] = {
  72.    {ID2_BEAU,              ID2_TRAILER,           ID2_BELLE,             ID2_LEAD},
  73.    {ID2_BELLE,             ID2_LEAD,              ID2_BEAU,              ID2_TRAILER}};
  74.  
  75. static int bit_table_1x4[][4] = {
  76.    {ID2_BEAU|ID2_END,        ID2_TRAILER|ID2_END,      ID2_BELLE|ID2_END,       ID2_LEAD|ID2_END},
  77.    {ID2_BELLE|ID2_CENTER,    ID2_LEAD|ID2_CENTER,      ID2_BEAU|ID2_CENTER,     ID2_TRAILER|ID2_CENTER},
  78.    {ID2_BELLE|ID2_END,       ID2_LEAD|ID2_END,         ID2_BEAU|ID2_END,        ID2_TRAILER|ID2_END},
  79.    {ID2_BEAU|ID2_CENTER,     ID2_TRAILER|ID2_CENTER,   ID2_BELLE|ID2_CENTER,    ID2_LEAD|ID2_CENTER}};
  80.  
  81. static int bit_table_1x8[][4] = {
  82.    {ID2_BEAU|ID2_OUTR6|ID2_OUTR2,   ID2_TRAILER|ID2_OUTR6|ID2_OUTR2, ID2_BELLE|ID2_OUTR6|ID2_OUTR2,  ID2_LEAD|ID2_OUTR6|ID2_OUTR2},
  83.    {ID2_BELLE|ID2_OUTR6|ID2_CTR6,   ID2_LEAD|ID2_OUTR6|ID2_CTR6,     ID2_BEAU|ID2_OUTR6|ID2_CTR6,    ID2_TRAILER|ID2_OUTR6|ID2_CTR6},
  84.    {ID2_BELLE|ID2_CTR2|ID2_CTR6,    ID2_LEAD|ID2_CTR2|ID2_CTR6,      ID2_BEAU|ID2_CTR2|ID2_CTR6,     ID2_TRAILER|ID2_CTR2|ID2_CTR6},
  85.    {ID2_BEAU|ID2_OUTR6|ID2_CTR6,    ID2_TRAILER|ID2_OUTR6|ID2_CTR6,  ID2_BELLE|ID2_OUTR6|ID2_CTR6,   ID2_LEAD|ID2_OUTR6|ID2_CTR6},
  86.    {ID2_BELLE|ID2_OUTR6|ID2_OUTR2,  ID2_LEAD|ID2_OUTR6|ID2_OUTR2,    ID2_BEAU|ID2_OUTR6|ID2_OUTR2,   ID2_TRAILER|ID2_OUTR6|ID2_OUTR2},
  87.    {ID2_BEAU|ID2_OUTR6|ID2_CTR6,    ID2_TRAILER|ID2_OUTR6|ID2_CTR6,  ID2_BELLE|ID2_OUTR6|ID2_CTR6,   ID2_LEAD|ID2_OUTR6|ID2_CTR6},
  88.    {ID2_BEAU|ID2_CTR2|ID2_CTR6,     ID2_TRAILER|ID2_CTR2|ID2_CTR6,   ID2_BELLE|ID2_CTR2|ID2_CTR6,    ID2_LEAD|ID2_CTR2|ID2_CTR6},
  89.    {ID2_BELLE|ID2_OUTR6|ID2_CTR6,   ID2_LEAD|ID2_OUTR6|ID2_CTR6,     ID2_BEAU|ID2_OUTR6|ID2_CTR6,    ID2_TRAILER|ID2_OUTR6|ID2_CTR6}};
  90.  
  91. static int bit_table_qtag[][4] = {
  92.    {ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6},
  93.    {ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6},
  94.    {ID2_CENTER|ID2_OUTR6, ID2_CENTER|ID2_OUTR6, ID2_CENTER|ID2_OUTR6, ID2_CENTER|ID2_OUTR6},
  95.    {ID2_CENTER|ID2_CTR2,  ID2_CENTER|ID2_CTR2,  ID2_CENTER|ID2_CTR2,  ID2_CENTER|ID2_CTR2},
  96.    {ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6},
  97.    {ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6},
  98.    {ID2_CENTER|ID2_OUTR6, ID2_CENTER|ID2_OUTR6, ID2_CENTER|ID2_OUTR6, ID2_CENTER|ID2_OUTR6},
  99.    {ID2_CENTER|ID2_CTR2,  ID2_CENTER|ID2_CTR2,  ID2_CENTER|ID2_CTR2,  ID2_CENTER|ID2_CTR2}};
  100.  
  101. static int bit_table_hrglass[][4] = {
  102.    {ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6},
  103.    {ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6},
  104.    {ID2_CENTER|ID2_OUTR6, ID2_CENTER|ID2_OUTR6, ID2_CENTER|ID2_OUTR6, ID2_CENTER|ID2_OUTR6},
  105.    {ID2_CENTER|ID2_CTR2,  ID2_CENTER|ID2_CTR2,  ID2_CENTER|ID2_CTR2,  ID2_CENTER|ID2_CTR2},
  106.    {ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6},
  107.    {ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6,    ID2_END|ID2_OUTR6},
  108.    {ID2_CENTER|ID2_OUTR6, ID2_CENTER|ID2_OUTR6, ID2_CENTER|ID2_OUTR6, ID2_CENTER|ID2_OUTR6},
  109.    {ID2_CENTER|ID2_CTR2,  ID2_CENTER|ID2_CTR2,  ID2_CENTER|ID2_CTR2,  ID2_CENTER|ID2_CTR2}};
  110.  
  111. static int bit_table_spindle[][4] = {
  112.    {ID2_CTR6,    ID2_CTR6,   ID2_CTR6,   ID2_CTR6},
  113.    {ID2_CTR6,    ID2_CTR6,   ID2_CTR6,   ID2_CTR6},
  114.    {ID2_CTR6,    ID2_CTR6,   ID2_CTR6,   ID2_CTR6},
  115.    {ID2_OUTR2,   ID2_OUTR2,  ID2_OUTR2,  ID2_OUTR2},
  116.    {ID2_CTR6,    ID2_CTR6,   ID2_CTR6,   ID2_CTR6},
  117.    {ID2_CTR6,    ID2_CTR6,   ID2_CTR6,   ID2_CTR6},
  118.    {ID2_CTR6,    ID2_CTR6,   ID2_CTR6,   ID2_CTR6},
  119.    {ID2_OUTR2,   ID2_OUTR2,  ID2_OUTR2,  ID2_OUTR2}};
  120.  
  121. #define BITS_TO_CLEAR (ID2_LEAD|ID2_TRAILER|ID2_BEAU|ID2_BELLE|ID2_CENTER|ID2_END|ID2_CTR2|ID2_CTR6|ID2_OUTR2|ID2_OUTR6)
  122. #define UNSYM_BITS_TO_CLEAR (ID2_NEARCOL|ID2_NEARLINE|ID2_NEARBOX|ID2_FARCOL|ID2_FARLINE|ID2_FARBOX)
  123.  
  124.  
  125.  
  126.  
  127. typedef int bit_table[4];
  128.  
  129. extern void update_id_bits(setup *ss)
  130.  
  131. {
  132.    int i, j;
  133.    bit_table *ptr;
  134.  
  135.    for (i=0; i<MAX_PEOPLE; i++) ss->people[i].id2 &= ~BITS_TO_CLEAR;
  136.  
  137.    switch (ss->kind) {
  138.       case s_1x2:
  139.          ptr = bit_table_1x2; break;
  140.       case s1x4:
  141.          ptr = bit_table_1x4; break;
  142.       case s2x2:
  143.          ptr = bit_table_2x2; break;
  144.       case s2x4:
  145.          ptr = bit_table_2x4; break;
  146.       case s1x8:
  147.          ptr = bit_table_1x8; break;
  148.       case s_qtag:
  149.          ptr = bit_table_qtag; break;
  150.       case s_hrglass:
  151.          ptr = bit_table_hrglass; break;
  152.       case s_spindle:
  153.          ptr = bit_table_spindle; break;
  154.       default:
  155.          return;
  156.    }
  157.  
  158.    j = setup_limits[ss->kind];
  159.    for (i=0; i<=j; i++) {
  160.       if (ss->people[i].id1 & BIT_PERSON)
  161.          ss->people[i].id2 |= ptr[i][ss->people[i].id1 & 3];
  162.    }
  163. }
  164.  
  165.  
  166. static expand_thing rear_wave_stuff = {{3, 0, 1, 2}, 4, s2x2, 0};
  167. static expand_thing rear_bone_stuff = {{0, 3, 2, 5, 4, 7, 6, 1}, 8, s2x4, 0};
  168. static expand_thing rear_wing_stuff = {{1, 2, 3, 4, 5, 6, 7, 0}, 8, s2x4, 0};
  169. static expand_thing rear_c1a_stuff = {{0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, 6, -1, 7, -1}, 16, s2x4, 0};
  170. static expand_thing rear_c1b_stuff = {{-1, 0, -1, 1, -1, 3, -1, 2, -1, 4, -1, 5, -1, 7, -1, 6}, 16, s2x4, 0};
  171. static expand_thing rear_c1c_stuff = {{6, -1, 7, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1}, 16, s2x4, 1};
  172. static expand_thing rear_c1d_stuff = {{-1, 7, -1, 6, -1, 0, -1, 1, -1, 3, -1, 2, -1, 4, -1, 5}, 16, s2x4, 1};
  173. static expand_thing rear_miniwave_stuff = {{1, 0}, 2, s_1x2, 1};
  174. static expand_thing rear_2x4_stuff = {{6, 7, 1, 0, 2, 3, 5, 4}, 8, s2x4, 1};
  175. static expand_thing rear_col_stuff = {{0, 3, 6, 5, 4, 7, 2, 1}, 8, s1x8, 0};
  176. static expand_thing rear_vrbox_stuff = {{1, 0, 3, 2}, 4, s1x4, 1};
  177. static expand_thing rear_hrbox_stuff = {{0, 3, 2, 1}, 4, s1x4, 0};
  178. static expand_thing rear_gwave_stuff = {{7, 0, 1, 6, 3, 4, 5, 2}, 8, s2x4, 0};
  179. static expand_thing rear_qtag_stuff = {{7, 0, 1, 2, 3, 4, 5, 6}, 8, s2x4, 1};
  180. static expand_thing rear_sqtag_stuff = {{0, 1, 2, 3}, 4, s1x4, 0};
  181.  
  182. static full_expand_thing rear_wave_pair     = {warn__rear_back,       0, &rear_wave_stuff};
  183. static full_expand_thing rear_bone_pair     = {warn__some_rear_back,  0, &rear_bone_stuff};
  184. static full_expand_thing rear_wing_pair     = {warn__some_rear_back,  0, &rear_wing_stuff};
  185. static full_expand_thing rear_c1a_pair      = {warn__some_rear_back,  0, &rear_c1a_stuff};
  186. static full_expand_thing rear_c1b_pair      = {warn__some_rear_back,  0, &rear_c1b_stuff};
  187. static full_expand_thing rear_c1c_pair      = {warn__some_rear_back,  0, &rear_c1c_stuff};
  188. static full_expand_thing rear_c1d_pair      = {warn__some_rear_back,  0, &rear_c1d_stuff};
  189. static full_expand_thing rear_miniwave_pair = {warn__rear_back,       0, &rear_miniwave_stuff};
  190. static full_expand_thing rear_2x4_pair      = {warn__rear_back,       0, &rear_2x4_stuff};
  191. static full_expand_thing rear_col_pair      = {warn__awful_rear_back, 0, &rear_col_stuff};
  192. static full_expand_thing rear_vrbox_pair    = {warn__awful_rear_back, 0, &rear_vrbox_stuff};
  193. static full_expand_thing rear_hrbox_pair    = {warn__awful_rear_back, 0, &rear_hrbox_stuff};
  194. static full_expand_thing rear_gwave_pair    = {warn__rear_back,       0, &rear_gwave_stuff};
  195. static full_expand_thing rear_qtag_pair     = {warn__rear_back,       0, &rear_qtag_stuff};
  196. static full_expand_thing rear_sqtag_pair    = {warn__awful_rear_back, 0, &rear_sqtag_stuff};
  197.  
  198. static expand_thing step_1x8_stuff = {{0, 7, 6, 1, 4, 3, 2, 5}, 8, s2x4, 0};
  199. static expand_thing step_1x4_side_stuff = {{0, 1, 2, 3}, 4, sdmd, 0};
  200. static expand_thing step_1x4_stuff = {{0, 3, 2, 1}, 4, s2x2, 0};
  201. static expand_thing step_1x2_stuff = {{0, 1}, 2, s_1x2, 1};
  202. static expand_thing step_2x2v_stuff = {{1, 2, 3, 0}, 4, s1x4, 0};
  203. static expand_thing step_2x2h_stuff = {{0, 1, 2, 3}, 4, s1x4, 1};
  204. static expand_thing step_8ch_stuff = {{7, 6, 0, 1, 3, 2, 4, 5}, 8, s2x4, 1};
  205. static expand_thing step_li_stuff = {{1, 2, 7, 4, 5, 6, 3, 0}, 8, s1x8, 0};
  206. static expand_thing step_tby_stuff = {{5, 6, 7, 0, 1, 2, 3, 4}, 8, s_qtag, 1};
  207.  
  208. static full_expand_thing step_1x8_pair =      {0, 0, &step_1x8_stuff};
  209. static full_expand_thing step_1x4_side_pair = {0, 0, &step_1x4_side_stuff};
  210. static full_expand_thing step_1x4_pair =      {0, 0, &step_1x4_stuff};
  211. static full_expand_thing step_2x2v_pair =     {0, 2*SETUPFLAG__ELONGATE_BIT, &step_2x2v_stuff};
  212. static full_expand_thing step_2x2h_pair =     {0, 1*SETUPFLAG__ELONGATE_BIT, &step_2x2h_stuff};
  213. static full_expand_thing step_8ch_pair =      {0, 0, &step_8ch_stuff};
  214. static full_expand_thing step_li_pair =       {0, 0, &step_li_stuff};
  215. static full_expand_thing step_tby_pair =      {0, 0, &step_tby_stuff};
  216. static full_expand_thing step_1x2_pair =      {0, 0, &step_1x2_stuff};
  217.  
  218.  
  219.  
  220. extern void touch_or_rear_back(
  221.    setup *scopy,
  222.    int callflags)
  223.  
  224. {
  225.    int i, j;
  226.    setup stemp;
  227.    full_expand_thing *tptr;
  228.    expand_thing *zptr;
  229.    int directions, livemask;
  230.  
  231.    directions = 0;
  232.    livemask = 0;
  233.    tptr = 0;
  234.  
  235.    for (i=0, j=1; i<=setup_limits[scopy->kind]; i++, j<<=1) {
  236.       int p = scopy->people[i].id1;
  237.       directions = (directions<<2) | (p&3);
  238.       if (p) livemask |= j;
  239.    }
  240.  
  241.    if (callflags & cflag__rear_back_from_r_wave) {
  242.       if (scopy->kind == s1x4 && (livemask == 0xF) && (directions == 0x28)) {
  243.          tptr = &rear_wave_pair;          /* Rear back from a wave to facing couples. */
  244.       }
  245.       else if (scopy->kind == s_1x2 && (livemask == 0x3) && (directions == 0x2)) {
  246.          tptr = &rear_miniwave_pair;      /* Rear back from a miniwave to facing people. */
  247.       }
  248.       else if (scopy->kind == s2x4) {
  249.          if ((livemask == 0xFF) && (directions == 0x2288)) {
  250.             tptr = &rear_2x4_pair;        /* Rear back from parallel waves to an 8 chain. */
  251.          }
  252.          else if ((livemask == 0xFF) && (directions == 0x55FF)) {
  253.             tptr = &rear_col_pair;        /* Rear back from columns to end-to-end single 8-chains. */
  254.          }
  255.       }
  256.       else if (scopy->kind == s2x2) {
  257.          if ((livemask == 0xF) && (directions == 0x28)) {
  258.             tptr = &rear_vrbox_pair;      /* Rear back from a right-hand box to a single 8 chain. */
  259.          }
  260.          else if ((livemask == 0xF) && (directions == 0x5F)) {
  261.             tptr = &rear_hrbox_pair;      /* Rear back from a right-hand box to a single 8 chain. */
  262.          }
  263.       }
  264.       else if (scopy->kind == s1x8 && (livemask == 0xFF) && (directions == 0x2882)) {
  265.          tptr = &rear_gwave_pair;         /* Rear back from a grand wave to facing lines. */
  266.       }
  267.       else if (scopy->kind == s_bone && livemask == 0xFF && ((directions == 0xA802) || (directions == 0x78D2))) {
  268.          /* Centers rear back from a "bone" to lines facing or "split square thru" setup. */
  269.          tptr = &rear_bone_pair;
  270.       }
  271.       else if (scopy->kind == s_rigger && livemask == 0xFF && ((directions == 0xA802) || (directions == 0xD872))) {
  272.          /* Ends rear back from a "wing" to lines facing or "split square thru" setup. */
  273.          tptr = &rear_wing_pair;
  274.       }
  275.       else if (scopy->kind == s_c1phan) {
  276.          /* Check for certain people rearing back from C1 phantoms. */
  277.          if ((livemask == 0x5555) && ((directions == 0x884C00C4) || (directions == 0x4C4CC4C4))) {
  278.             tptr = &rear_c1a_pair;
  279.          }
  280.          else if ((livemask == 0xAAAA) && ((directions == 0x13223100) || (directions == 0x13313113))) {
  281.             tptr = &rear_c1b_pair;
  282.          }
  283.          else if ((livemask == 0x5555) && ((directions == 0x08CC8044) || (directions == 0x08808008))) {
  284.             tptr = &rear_c1c_pair;
  285.          }
  286.          else if ((livemask == 0xAAAA) && ((directions == 0x11203302) || (directions == 0x20200202))) {
  287.             tptr = &rear_c1d_pair;
  288.          }
  289.       }
  290.    }
  291.    else if (callflags & cflag__rear_back_from_qtag) {
  292.       if (scopy->kind == s_qtag && livemask == 0xFF && ((directions == 0x08A2) || (directions == 0xA802))) {
  293.          tptr = &rear_qtag_pair;         /* Have the centers rear back from a 1/4 tag or 3/4 tag. */
  294.       }
  295.       else if (scopy->kind == sdmd && livemask == 0xF && ((directions == 0x5F) || (directions == 0xD7))) {
  296.          tptr = &rear_sqtag_pair;         /* Have the centers rear back from a single 1/4 tag or 3/4 tag. */
  297.       }
  298.    }
  299.    else {      /* We know that (callflags & cflag__step_to_wave) is true here. */
  300.       switch (scopy->kind) {
  301.          case s2x2:
  302.             if ((livemask == 0xF) && (directions == 0x7D)) {
  303.                tptr = &step_2x2h_pair;
  304.             }
  305.             else if ((livemask == 0xF) && (directions == 0xA0)) {
  306.                tptr = &step_2x2v_pair;
  307.             }
  308.             break;
  309.          case s2x4:
  310.             if ((livemask == 0xFF) && (directions == 0x77DD)) {
  311.                tptr = &step_8ch_pair;         /* Check for stepping to parallel waves from an 8 chain. */
  312.             }
  313.             else if ((livemask == 0xFF) && (directions == 0xAA00)) {
  314.                tptr = &step_li_pair;          /* Check for stepping to a grand wave from lines facing. */
  315.             }
  316.             else if ((livemask == 0xFF) && ((directions == 0xDD77) || (directions == 0x5FF5))) {
  317.                tptr = &step_tby_pair;         /* Check for stepping to a 1/4 tag or 3/4 tag from a DPT or trade-by. */
  318.             }
  319.             break;
  320.          case s_1x2:
  321.             if ((livemask == 0x3) && (directions == 0x7)) {
  322.                tptr = &step_1x2_pair;         /* Check for stepping to a miniwave from people facing. */
  323.             }
  324.             break;
  325.          case s1x4:
  326.             /* Check for stepping to a box from a 1x4 single 8 chain -- we allow some phantoms.  This is what makes
  327.                triple columns turn and weave legal in certain interesting cases. */
  328.             if ((livemask == 0xF) && (directions == 0x7D))
  329.                tptr = &step_1x4_pair;
  330.             else if ((livemask == 0x3) && (directions == 0x70))
  331.                tptr = &step_1x4_pair;
  332.             else if ((livemask == 0xC) && (directions == 0x0D))
  333.                tptr = &step_1x4_pair;
  334.             /* Check for stepping to a single 1/4 tag or 3/4 tag from a single-file DPT or trade-by --
  335.                we allow some phantoms, as above. */
  336.             else if ((livemask == 0xF) && ((directions == 0xD7) || (directions == 0x5F)))
  337.                tptr = &step_1x4_side_pair;
  338.             else if ((livemask == 0xA) && (directions == 0x13))
  339.                tptr = &step_1x4_side_pair;
  340.             break;
  341.          case s1x8:
  342.             if ((livemask == 0xFF) && (directions == 0x7DD7)) {
  343.                tptr = &step_1x8_pair;         /* Check for stepping to a column from a 1x8 single 8 chain. */
  344.             }
  345.             break;
  346.       }
  347.    }
  348.  
  349.    if (!tptr) return;
  350.    if (tptr->warning) warn(tptr->warning);
  351.    if (scopy->setupflags & tptr->forbidden_elongation)
  352.       fail("People are too far away to work with each other on this call.");
  353.    zptr = tptr->expand_lists;
  354.  
  355.    scopy->setupflags |= SETUPFLAG__DISTORTED;
  356.  
  357.    stemp = *scopy;
  358.    clear_people(scopy);
  359.  
  360.    if (zptr->rot) {
  361.       for (i=0; i<zptr->size; i++) {
  362.          int idx = zptr->source_indices[i];
  363.          if (idx < 0) {
  364.             if (stemp.people[i].id1) fail("Don't understand this setup at all.");
  365.          }
  366.          else {
  367.             (void) copy_rot(scopy, idx, &stemp, i, 033);
  368.          }
  369.       }
  370.       scopy->rotation++;
  371.    }
  372.    else {
  373.       for (i=0; i<zptr->size; i++) {
  374.          int idx = zptr->source_indices[i];
  375.          if (idx < 0) {
  376.             if (stemp.people[i].id1) fail("Don't understand this setup at all.");
  377.          }
  378.          else {
  379.             (void) copy_person(scopy, idx, &stemp, i);
  380.          }
  381.       }
  382.    }
  383.  
  384.    scopy->kind = zptr->outer_kind;
  385.    canonicalize_rotation(scopy);
  386. }
  387.  
  388.  
  389.  
  390. /* Top level move routine. */
  391.  
  392. extern void toplevelmove(void)
  393. {
  394.    setup stemp;
  395.    int i, j, livemask;
  396.    expand_thing *eptr;
  397.    parse_block *conceptptr;
  398.    parse_block *cptr;
  399.    final_set new_final_concepts;
  400.    setup new_setup;
  401.  
  402.    int concept_read_base = 0;
  403.    setup starting_setup = history[history_ptr].state;
  404.    configuration *newhist = &history[history_ptr+1];
  405.    /* Be sure that the amount of written history that we consider to be safely
  406.       written is less than the item we are about to change. */
  407.    if (written_history_items > history_ptr)
  408.       written_history_items = history_ptr;
  409.  
  410.    starting_setup.setupflags = 0;
  411.  
  412.    /* If we are starting a sequence with the "so-and-so into the center and do whatever"
  413.       flag on, and this call is a "sequence starter", take special action. */
  414.  
  415.    if (startinfolist[history[history_ptr].centersp].into_the_middle) {
  416.    
  417.       /* If the call is a special sequence starter (e.g. spin a pulley) remove the implicit
  418.          "centers" concept and just do it.  The setup in this case will be a squared set
  419.          with so-and-so moved into the middle, which is what the encoding of these calls
  420.          wants. */
  421.    
  422.       if (parse_state.topcallflags & cflag__sequence_starter)
  423.          concept_read_base = 1;
  424.    
  425.       /* If the call is a "split square thru" type of call, we do the same.  We leave the
  426.          "split" concept in place.  Other mechanisms will do the rest. */
  427.  
  428.       else if ((parse_state.topcallflags & cflag__split_like_square_thru) &&
  429.             ((newhist->command_root->next->concept->kind == concept_split) ||
  430.                   ((newhist->command_root->next->concept->kind == concept_left) &&
  431.                   (newhist->command_root->next->next->concept->kind == concept_split))))
  432.          concept_read_base = 1;
  433.  
  434.       /* If the call is a "split dixie style" type of call, we do something similar,
  435.          but the transformation we perform on the starting setup is highly peculiar. */
  436.    /* ****** bug: ability to handle "left" concept patched out!  It does it wrong! */
  437.    
  438.       else if ((parse_state.topcallflags & cflag__split_like_dixie_style) &&
  439.                newhist->command_root->next->concept->kind == concept_split &&
  440.                newhist->command_root->next->next->concept->kind == marker_end_of_list) {
  441.          personrec x;
  442.  
  443.          concept_read_base = 2;
  444.          starting_setup.rotation++;
  445.          x = starting_setup.people[0];
  446.          (void) copy_rot(&starting_setup, 0, &starting_setup, 6, 022);
  447.          (void) copy_person(&starting_setup, 6, &starting_setup, 5);
  448.          (void) copy_rot(&starting_setup, 5, &starting_setup, 7, 033);
  449.          starting_setup.people[7].id1 = rotccw(x.id1);
  450.          starting_setup.people[7].id2 = x.id2;
  451.  
  452.          x = starting_setup.people[4];
  453.          (void) copy_rot(&starting_setup, 4, &starting_setup, 2, 022);
  454.          (void) copy_person(&starting_setup, 2, &starting_setup, 1);
  455.          (void) copy_rot(&starting_setup, 1, &starting_setup, 3, 033);
  456.          starting_setup.people[3].id1 = rotccw(x.id1);
  457.          starting_setup.people[3].id2 = x.id2;
  458.       }
  459.    }
  460.  
  461.    if (concept_read_base == 2)
  462.       conceptptr = newhist->command_root->next->next;
  463.    else if (concept_read_base == 1)
  464.       conceptptr = newhist->command_root->next;
  465.    else
  466.       conceptptr = newhist->command_root;
  467.  
  468.    /* Clear a few things.  We do NOT clear the warnings, because some (namely the
  469.       "concept not allowed at this level" warning) may have already been logged. */
  470.    newhist->centersp = 0;
  471.    newhist->draw_pic = FALSE;
  472.    newhist->resolve_flag.kind = resolve_none;
  473.  
  474.    /* Set the selector to "uninitialized", so that, if we do a call like "run", we
  475.       will query the user to find out who is selected. */
  476.  
  477.    current_selector = selector_uninitialized;
  478.  
  479.    /* This next thing is not really right.  It makes the program refuse to step to a wave     */
  480.    /*   or rear back from one if any concepts are in use.  Actually, we should allow          */
  481.    /*   a few concepts, such as left.  We should only disallow concepts where the change of   */
  482.    /*   shape resulting from the stepping to a wave or rearing back alters the interpretation */
  483.    /*   of the concept.  For example, the evaluation of split phantom lines would be ruined   */
  484.    /*   if an implicit step to a wave occurred.                                               */
  485.  
  486.    /* We must check for rearing back from a wave or stepping to one.  Do this only if there are
  487.       no virtual-setup concepts.  The way we find out is to pass over
  488.       all the final concepts and demand that the next thing be the end of the concept list.
  489.       If this test is satisfied, just call move. */
  490.  
  491.    cptr = process_final_concepts(conceptptr, TRUE, &new_final_concepts);
  492.  
  493.    if (cptr->concept->kind <= marker_end_of_list) {
  494.  
  495.       /* We make move re-read the final concepts.  ***** Is this necessary? */
  496.  
  497.       goto do_the_call;
  498.    }
  499.  
  500.    /* We seem to have a virtual-setup concept.  See if the matrix needs to be expanded. */
  501. /* ****** We should just use the left-over cptr, and demand that the new final mask be zero. */
  502.  
  503.    cptr = conceptptr;
  504.    while (cptr->concept->kind == concept_comment) cptr = cptr->next;
  505.    if (cptr->concept->kind == concept_standard) cptr = cptr->next;
  506.    while (cptr->concept->kind == concept_comment) cptr = cptr->next;
  507.  
  508.    tryagain:
  509.  
  510.    if (concept_table[cptr->concept->kind].concept_prop & (CONCPROP__NEED_4X4 | CONCPROP__NEED_BLOB | CONCPROP__NEED_4X6)) {
  511.       if (starting_setup.kind == s2x4) {
  512.          eptr = &exp_2x4_4x4_stuff; goto expand_me;
  513.       }
  514.    }
  515.  
  516.    if (concept_table[cptr->concept->kind].concept_prop & (CONCPROP__NEED_BLOB)) {
  517.       if (starting_setup.kind == s4x4) {
  518.          eptr = &exp_4x4_blob_stuff; goto expand_me;
  519.       }
  520.    }
  521.    else if (concept_table[cptr->concept->kind].concept_prop & CONCPROP__NEED_4DMD) {
  522.       switch (starting_setup.kind) {
  523.          case s1x8:
  524.             eptr = &exp_1x8_4dm_stuff; goto expand_me;
  525.          case s_qtag:
  526.             eptr = &exp_qtg_4dm_stuff; goto expand_me;
  527.          case s4x4:
  528.             for (i=0, j=1, livemask=0; i<16; i++, j<<=1) {
  529.                if (starting_setup.people[i].id1) livemask |= j;
  530.             }
  531.  
  532.             if (livemask == 0x1717) {
  533.                eptr = &exp_4x4_4dm_stuff_a; goto expand_me;
  534.             }
  535.             else if (livemask == 0x7171) {
  536.                eptr = &exp_4x4_4dm_stuff_b; goto expand_me;
  537.             }
  538.       }
  539.    }
  540.    else if (concept_table[cptr->concept->kind].concept_prop & CONCPROP__NEED_3DMD) {
  541.       if (starting_setup.kind == s_3x1dmd) {         /* Need to expand to real triple diamonds. */
  542.          eptr = &exp_3x1d_3d_stuff; goto expand_me;
  543.       }
  544.    }
  545.    else if (concept_table[cptr->concept->kind].concept_prop & CONCPROP__NEED_2X8) {
  546.       switch (starting_setup.kind) {         /* Need to expand to a 2x8. */
  547.          case s2x4:
  548.             eptr = &exp_2x4_2x8_stuff; goto expand_me;
  549.          case s2x6:
  550.             eptr = &exp_2x6_2x8_stuff; goto expand_me;
  551.       }
  552.    }
  553.    else if (concept_table[cptr->concept->kind].concept_prop & CONCPROP__NEED_2X6) {
  554.       if (starting_setup.kind == s2x4) {         /* Need to expand to a 2x6. */
  555.          eptr = &exp_2x4_2x6_stuff; goto expand_me;
  556.       }
  557.    }
  558.    else if (concept_table[cptr->concept->kind].concept_prop & CONCPROP__NEED_4X6) {
  559.       if (starting_setup.kind == s2x6) {         /* Need to expand to a 4x6. */
  560.          eptr = &exp_2x6_4x6_stuff; goto expand_me;
  561.       }
  562.    }
  563.    else {
  564.       switch (cptr->concept->kind) {
  565.          case concept_triple_lines: case concept_triple_lines_together:
  566.             if (starting_setup.kind == s_qtag) {         /* Need to expand to a 3x4. */
  567.                eptr = &exp_qtg_3x4_stuff; goto expand_me;
  568.             }
  569.             break;
  570.       }
  571.    }
  572.  
  573.    /* If get here, we did NOT see any concept that requires a setup expansion. */
  574.  
  575.    goto do_the_call;
  576.  
  577.    expand_me:
  578.  
  579.    /* If get here, we DID see a concept that requires a setup expansion. */
  580.  
  581.    stemp = starting_setup;
  582.    clear_people(&starting_setup);
  583.    if (eptr->rot) {
  584.       for (i=0; i<eptr->size; i++) (void) copy_rot(&starting_setup, eptr->source_indices[i], &stemp, i, 033);
  585.       starting_setup.rotation++;
  586.    }
  587.    else {
  588.       for (i=0; i<eptr->size; i++) (void) copy_person(&starting_setup, eptr->source_indices[i], &stemp, i);
  589.    }
  590.  
  591.    starting_setup.kind = eptr->outer_kind;
  592.    canonicalize_rotation(&starting_setup);
  593.  
  594.    goto tryagain;
  595.  
  596.    do_the_call:
  597.  
  598.    /* Put in identification bits for unsymmetrical stuff, if possible. */
  599.  
  600.    for (i=0; i<MAX_PEOPLE; i++) starting_setup.people[i].id2 &= ~UNSYM_BITS_TO_CLEAR;
  601.  
  602.    if (starting_setup.kind == s2x4) {
  603.       int nearbit = 0;
  604.       int farbit = 0;
  605.  
  606.       if (starting_setup.rotation & 1) {
  607.          nearbit = ID2_NEARBOX;
  608.          farbit = ID2_FARBOX;
  609.       }
  610.       else {
  611.          int tbonetest = 0;
  612.          for (i=0; i<8; i++) tbonetest |= starting_setup.people[i].id1;
  613.  
  614.          if (!(tbonetest & 1)) {
  615.             nearbit = ID2_NEARLINE;
  616.             farbit = ID2_FARLINE;
  617.          }
  618.          else if (!(tbonetest & 010)) {
  619.             nearbit = ID2_NEARCOL;
  620.             farbit = ID2_FARCOL;
  621.          }
  622.       }
  623.  
  624.       for (i=0; i<8; i++) {
  625.          if (starting_setup.people[i].id1 & BIT_PERSON)
  626.             starting_setup.people[i].id2 |= ((i + (starting_setup.rotation << 1)) & 4) ? nearbit:farbit;
  627.       }
  628.    }
  629.  
  630.    /* Put in position-identification bits (leads/trailers/beaux/belles/centers/ends etc.) */
  631.  
  632.    update_id_bits(&starting_setup);
  633.    move(&starting_setup, conceptptr, NULLCALLSPEC, 0, FALSE, &new_setup);
  634.  
  635.    /* Remove outboard phantoms from the resulting setup. */
  636.  
  637.    normalize_setup(&new_setup, simple_normalize);
  638.  
  639.    newhist->state = new_setup;
  640.    newhist->resolve_flag = resolve_p(&new_setup);
  641. }
  642.